<template>
  <div>
    <!-- 卡片 -->
    <el-card style="">
      <!-- button -->
      <el-button
        type="primary"
        size="default"
        icon="plus"
        @click="addTrademark"
        v-has="`btn.TradeMark.add`"
      >
        添加商品
      </el-button>
      <!-- 表格 -->
      <el-table style="width: 100%" border :data="trademarkArr">
        <el-table-column label="序号" width="180" type="index" />
        <el-table-column label="品牌名称" width="180" prop="tmName">
          <template #="{ row, $index }">
            <!-- row默认为数组中的对象 -->
            <pre>{{ row.tmName }}</pre>
          </template>
        </el-table-column>
        <el-table-column label="品牌Logo">
          <template #="{ row, $index }">
            <img :src="row.logUrl" alt="" />
          </template>
        </el-table-column>
        <el-table-column label="品牌操作">
          <template #="{ row, $index }">
            <el-button
              type="primary"
              size="small"
              icon="Edit"
              @click="updateTrademark(row)"
            ></el-button>

            <!-- 气泡确认框 -->
            <el-popconfirm
              title="确定要删除已有品牌吗?"
              icon="Delete"
              @confirm="removeTrademark(row.id)"
            >
              <template #reference>
                <el-button
                  type="primary"
                  size="small"
                  icon="Delete"
                ></el-button>
              </template>
            </el-popconfirm>
          </template>
        </el-table-column>
      </el-table>

      <!-- 分页器 -->
      <el-pagination
        v-model:current-page="pageNo"
        v-model:page-size="limit"
        @current-change="getHasTrademark"
        @size-change="sizeChange"
        :page-sizes="[3, 5, 7, 9]"
        :disabled="false"
        :background="true"
        layout="total, sizes, prev, pager, ->,next, jumper"
        :total="total"
      />
    </el-card>
    <!-- 对话框组件：在添加和修改品牌时使用 -->
    <!-- v-model负责控制对话框的显示与隐藏true显示，false隐藏-->
    <el-dialog
      v-model="dialogFormVisible"
      :title="trademarkParams.id ? '修改品牌' : '添加品牌'"
      width="500"
    >
      <el-form
        style="width: 80%"
        :model="trademarkParams"
        :rules="rules"
        ref="formRef"
      >
        <el-form-item label="品牌名称" label-width="100px" prop="tmName">
          <el-input
            placeholder="请输入您的品牌名称"
            v-model="trademarkParams.tmName"
          ></el-input>
        </el-form-item>
        <el-form-item label="品牌Logo" label-width="100px" prop="logoUrl">
          <!-- upload组件属性action：上传文件的接口地址，需要添加上/api，否则服务器不发送这次post请求 -->
          <el-upload
            class="avatar-uploader"
            action="/api/admin/product/fileUpload"
            :show-file-list="false"
            :on-success="handleAvatarSuccess"
            :before-upload="beforeAvatarUpload"
          >
            <img
              v-if="trademarkParams.logoUrl"
              :src="trademarkParams.logoUrl"
              class="avatar"
            />
            <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
          </el-upload>
        </el-form-item>
      </el-form>
      <!-- 具名插槽#footer -->
      <template #footer>
        <el-button type="primary" size="default" @click="cancel">
          取消
        </el-button>
        <el-button type="primary" size="default" @click="confirm">
          确定
        </el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script lang="ts" setup>
import { ref, onMounted, reactive } from 'vue'
//引入接口定义的类型
import type {
  Records,
  TradeMark,
  TradeMarkResponseData,
} from '@/api/product/trademark/type'
//引入相应模块的接口方法
import {
  reqHasTrademark,
  reqAddOrUpdateTrademark,
  reqDeleteTrademark,
} from '@/api/product/trademark'
import { ElMessage } from 'element-plus'
import { Plus } from '@element-plus/icons-vue'
import type { UploadProps } from 'element-plus'
//当前页码
let pageNo = ref<number>(1)
//每一页展示多少条数据
let limit = ref<number>(3)
//存储已有品牌的数据总数
let total = ref<number>(100)
//存储已有品牌的数据
let trademarkArr = ref<Records>([])
//控制对话框的显示与隐藏
let dialogFormVisible = ref<boolean>(false)
//收集新增品牌的数据
let trademarkParams = reactive<TradeMark>({
  tmName: '',
  logoUrl: '',
})
//获取el-form组件实例
let formRef = ref()
//将商品管理的接口方法封装为一个函数：在任何情况下获取数据，调用此函数即可
const getHasTrademark = async (pager = 1) => {
  //调用此方法时如果没有传递pageNo默认回到第一页
  pageNo.value = pager
  let result: TradeMarkResponseData = await reqHasTrademark(
    pageNo.value,
    limit.value,
  )
  if (result.code == 200) {
    total.value = result.data.total
    trademarkArr.value = result.data.records
  }
}
//组件一旦挂载完毕--发送一次请求获取数据
onMounted(() => {
  getHasTrademark()
})
//点击其他分页触发事件@current-change="getHasTrademark"
//点击下拉菜单时数据发生变化也触发此方法
function sizeChange() {
  //改变每页的数据条数时，默认回到第一页
  getHasTrademark()
}
//添加品牌按钮,显示对话框
function addTrademark() {
  dialogFormVisible.value = true
  trademarkParams.id = 0
  trademarkParams.tmName = ''
  trademarkParams.logoUrl = ''
  //每次显示对话框需要清除上一次的校验信息
  //ts问号写法，如果获取到formRef组件实例就执行，未获取到就不执行
  formRef.value?.clearValidate('tmName')
  formRef.value?.clearValidate('logoUrl')
}
//修改品牌按钮,显示对话框
function updateTrademark(row: TradeMark) {
  dialogFormVisible.value = true
  trademarkParams.id = row.id
  //展示已有品牌的数据才能进行修改
  //ES6语法合并对象，将row与trademarkParems属性与属性值进行合并
  Object.assign(trademarkParams, row)
  //每次显示对话框需要清除上一次的校验信息
  //ts问号写法，如果获取到formRef组件实例就执行，未获取到就不执行
  formRef.value?.clearValidate('logoUrl')
}
function cancel() {
  dialogFormVisible.value = false
}
async function confirm() {
  //在点击确定发送请求之前，对整个表单进行校验
  //valiate()对整个表单内容进行校验，校验成功才执行后续代码，接收一个回调函数或返回promise
  await formRef.value.validate()
  let result: any = await reqAddOrUpdateTrademark(trademarkParams)
  //添加/修改品牌成功
  if (result.code === 200) {
    dialogFormVisible.value = false
    ElMessage({
      type: 'success',
      message: trademarkParams.id ? '修改品牌成功' : '添加品牌成功',
    })
    //再次发请求获取所有的商品数使得商品总数改变
    getHasTrademark(trademarkParams.id ? pageNo.value : 1)
    //再次点开对话框要把信息清空
  } else {
    //添加失败
    ElMessage({
      type: 'error',
      message: trademarkParams.id ? '修改品牌失败' : '添加品牌失败',
    })
    dialogFormVisible.value = false
  }
}
//upload组件->上传图片之前触发的钩子函数，在上传图片成功之前触发用来限制文件的格式与大小
const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
  if (
    rawFile.type == 'image/jpeg' ||
    rawFile.type == 'image/png' ||
    rawFile.type == 'image/gif'
  ) {
    if (rawFile.size / 1024 / 1024 < 4) {
      return true
    } else {
      ElMessage({
        type: 'error',
        message: '上传的文件大小需小于4M',
      })
      return false
    }
  } else {
    ElMessage({
      type: 'error',
      message: '文件格式不匹配',
    })
    return false
  }
}
//上传图片成功触发的钩子函数
const handleAvatarSuccess: UploadProps['onSuccess'] = (
  response,
  uploadFile,
) => {
  //response即为当前图片上传，post请求服务器返回的数据
  //收集上传图片的地址，添加时带给服务器
  trademarkParams.logoUrl = response.data
  //图片上传成功，清除掉表单校验信息
  formRef.value.clearValidate('tmName')
  formRef.value.clearValidate('logoUrl')
}
//表单校验规则对象
const rules = {
  tmName: [
    //required:如果值为真，表示这字段必须校验，表单前面会出现五角星
    //trigger：校验规则的触发时机（blur失去焦点时），（change字段发生改变时）
    //validator:自定义校验规则的函数
    { required: true, trigger: 'blur', validator: validatorTmName },
  ],
  logoUrl: [{ required: true, trigger: 'blur', validator: validatorlogoUrl }],
}
function validatorTmName(_rule: any, value: any, callBack: any) {
  //自定义校验规则
  if (value.trim().length >= 2) {
    callBack()
  } else {
    callBack(new Error('品牌名称需大于或等于两位'))
  }
}
function validatorlogoUrl(_rule: any, value: any, callBack: any) {
  //如果图片上传获取到图片地址
  if (value) {
    callBack()
  } else {
    callBack(new Error('logo图片务必上传'))
  }
}
//气泡确认框确认删除的方法
async function removeTrademark(id: number) {
  let result = await reqDeleteTrademark(id)
  if (result.code === 200) {
    ElMessage({
      type: 'success',
      message: '删除信息成功！',
    })
    getHasTrademark(
      trademarkArr.value.length > 1 ? pageNo.value : pageNo.value - 1,
    )
  } else {
    ElMessage({
      type: 'error',
      message: '删除信息失败',
    })
  }
}
</script>
<style lang="scss">
.avatar-uploader .el-upload {
  border: 1px dashed var(--el-border-color);
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: var(--el-transition-duration-fast);
}

.avatar-uploader .el-upload:hover {
  border-color: var(--el-color-primary);
}

.el-icon.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 178px;
  height: 178px;
  text-align: center;
}
</style>
